/*
 * $Id: validation.js 632335 2008-02-29 15:00:18Z jeromy $
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
/**
 * Override the default function, support to clear the child table 
 * 
 * @param form
 * @return
 */
function clearErrorMessagesXHTML(form) {

    // get field table
    var table;
    for (var i = 0; i < form.childNodes.length; i++) {
        if (form.childNodes[i].tagName != null && form.childNodes[i].tagName.toLowerCase() == 'table') {
            table = form.childNodes[i];
            break;
        }
    }

    if (table == null) {
        return;
    }

    // clear out any rows with an "errorFor" attribute
    var rows = table.rows;
    if (rows == null){
        return;
    }

    var rowsToDelete = new Array();
    for(var i = 0; i < rows.length; i++) {
        var r = rows[i];
        // allow blank errorFor values on dojo markup
        if (r.getAttribute("errorFor") != null) {
            rowsToDelete.push(r);
        }
        
        // clear the child table
        for (var j = 0; j < r.childNodes.length; j++) {
        	var c = r.childNodes[j];
        	clearErrorMessagesXHTML(c);
        }
    }

    // now delete the rows
    for (var i = 0; i < rowsToDelete.length; i++) {
        var r = rowsToDelete[i];
        table.deleteRow(r.rowIndex);
        //table.removeChild(rowsToDelete[i]); 
    }
}

function validateCollection(name) {
	
}

/**
 * Add a new row after the selected element
 * 
 * @param element
 * @param useMetadata
 * @return
 */
function addRow(element, useMetadata) {
	var row = findRow(element);
	if (row == null) {
		return;
	}
	var table = findTable(row);
	if (table == null) {
		return;
	}
	
	// calculate the inserted position & new row index
	var position = row.rowIndex + 1;
	var indexValue = findIndex(row.innerHTML) + 1;
	
	// find meta data
	var context = null;
	if (useMetadata) {
		context = table.getAttribute('rowMetadata');
		if (context == null && (row.rowIndex + 1) < table.rows.length) {
			// FIXME: right? -- the correct meta data follows selected row
			row = table.rows[row.rowIndex + 1];
		}
	}
	// use the selected row as the meta data
	if (context == null) {
		context = row.innerHTML;
	}
	
	// replace [x] by [x + 1]
	var next = 0;
	var index = context.indexOf('[');
	var newContext = '';
	while (index > 0) {
		newContext += context.substring(next, index);
		next = context.indexOf(']', index + 1);
		if (next > index) {
			newContext += '[' + indexValue
			index = context.indexOf('[', next + 1);
		}
	}
	newContext += context.substring(next, context.length);
	
	// create new row
	var newRow = table.insertRow(position);
	newRow.innerHTML = newContext;
	
	// update the row index after the new added row
	updateRowIndex(table, position + 1, indexValue + 1);
}

function updateRowIndex(table, beginRowIndex, beginIndex) {
	var rows = table.rows;
	var rowLen = rows.length;
	
	for(var i = beginRowIndex; i < rowLen; i++) {
        var row = rows[i];
        
        updateNode(row, beginIndex);
		beginIndex++;
	}//for table
}

// update all node name from [x] to [newIndex]
function updateNode(node, newIndex) {
	for (var j = 0; j < node.childNodes.length; j++) {
		var child = node.childNodes[j];
		
		if (child.childNodes.length == 0) {
			var name = child.name;
			
			if (name != null && name.length > 0) {
				var index = name.indexOf('[');
				var next = name.indexOf(']', index + 1);
				if (next > index) {
					name = name.substring(0, index + 1) + newIndex + name.substring(next);
				}
				child.name = name;
			}
		} else {
			updateNode(child, newIndex);
		}
	} // for each child node
}

function removeRow(element) {
	var row = findRow(element);
	if (row == null) {
		return;
	}
	var table = findTable(row);
	if (table == null) {
		return;
	}
	
	var rowIndex = row.rowIndex;
	var context = row.innerHTML;
	
	// save meta data
	if (table.getAttribute('rowMetadata') == null) {
		table.setAttribute('rowMetadata', context);
	}
	
	table.deleteRow(rowIndex);
	
	var beginIndex = findIndex(context);
	if (beginIndex == -1) {
		beginIndex = 0;
	}
	updateRowIndex(table, rowIndex, beginIndex);
}

/////////////////////////////////// private method ////////////////////////////
// find x from [x]
function findIndex(context) {
	var index = context.indexOf('[');
	next = context.indexOf(']', index + 1);
	var beginIndex = -1;
	if (next > index) {
		beginIndex = parseInt(context.substring(index + 1, next));
	}
	return beginIndex;
}

function findTable(row) {
	var table = row;
	do {
		table = table.parentNode;
	} while(table != null && table.tagName.toLowerCase() != 'table');
	return table;
}

function findRow(element) {
	var row = null;
	// find the row
	do {
		if (row == null) {
			row = element;
		} else {
			row = row.parentNode;
		}
	} while(row != null && row.tagName.toLowerCase() != 'tr');
	return row;
}